package ee.ttu.lecture;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.KeyFactory;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.googlecode.objectify.Key;

import ee.ttu.lecture.data.Lecture;
import ee.ttu.lecture.data.Rating;
import ee.ttu.lecture.data.User;
import ee.ttu.lecture.form.LectureForm;

@SuppressWarnings("serial")
public class LectureServlet extends HttpServlet
{
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
	{
		
		PageAssembler assembler = new PageAssembler(req, resp);
		DataAccess access = DataAccess.getDataAccess();
		
		String action = req.getParameter("action");
		String mode = req.getParameter("mode");
		String id = req.getParameter("id");
		
		
		if(mode == null || action == null)
		{
			resp.sendRedirect(req.getContextPath() + "/lecture?mode=lecture&action=list");
		}
		else if(mode.equals("lecture") && action.equals("list"))
		{
			assembler.assembleMainView();
		}
		else if(mode.equals("lecture") && action.equals("new"))
		{
			assembler.assembleLectureView();
		}
		else if(mode.equals("lecture") && action.equals("edit") && id != null)
		{
			assembler.assembleLectureView();
				
			/* convert key string to id
			 * Key<User> key = new Key<User>(KeyFactory.stringToKey(id));
			 * long id1 = key.getId()
			 */
			
			/*
			 * convert id to html friendly key string
			Key<User> key = new Key<User>(User.class, user.getId());
			String id = KeyFactory.keyToString(key.getRaw());
			*/
		}
		else if(mode.equals("lecture") && action.equals("store"))
		{
			LectureForm form = LectureForm.getLectureForm(req);
			Lecture lecture = form.convertToLecture();
			
			if(lecture != null)
			{
				if(id != null) //kui update lisa juurde id
				{
					Key<Lecture> key = new Key<Lecture>(KeyFactory.stringToKey(id));
					lecture.setId(key.getId());
				}
				access.storeLecture(lecture);
				resp.sendRedirect(req.getContextPath() + "/lecture");
			}
			else
			{
				req.setAttribute("lectureForm", form);
				RequestDispatcher dispatcher;
				if(id != null) {
					dispatcher = req.getRequestDispatcher("lecture?mode=lecture&action=edit&id=" + id);
				}
				else dispatcher = req.getRequestDispatcher("lecture?mode=lecture&action=new");
				if(dispatcher != null) dispatcher.forward(req, resp);
				
			}
			
		}
		else if(mode.equals("lecture") && action.equals("delete"))
		{
			//resp.sendRedirect(req.getContextPath() + "/trackerservice");
		}
		else if(mode.equals("lecture") && action.equals("get"))
		{
			String json = "";
			if(id != null)
			{
				json = "{}";
				try
				{
					long idAsLong = Long.parseLong(id);
					if(idAsLong == 0) throw new NumberFormatException();
					Lecture lecture = access.getLecture(idAsLong);
					if(lecture != null)
					{
						Gson gson = new Gson();
						json = gson.toJson(lecture);
					}
				}
				catch(NumberFormatException ex)
				{};
			}
			else
			{
				List<Lecture> lectureList = access.getLectures();
				json = "[]";
				if(lectureList != null)
				{
					Gson gson = new Gson();
					json = gson.toJson(lectureList);
				}
			}
			
			resp.setStatus(HttpServletResponse.SC_OK);
			resp.getWriter().println(json);
		}
		else if(mode.equals("user") && action.equals("store"))
		{
			String username = req.getParameter("username");
			if(username != null)
			{ 
				if(!username.equals(""))
				{
					User user = new User();
					user.setUsername(username);
					access.storeUser(user);
				}
			}
			resp.sendRedirect(req.getContextPath() + "/lecture?mode=lecture&action=list");
		}
		else if(mode.equals("user") && action.equals("get"))
		{
			String username = req.getParameter("username");
			if(username != null)
			{
				User user = access.getUserByName(username);
				String json = "{}";
				if(user != null)
				{
					Gson gson = new Gson();
					json = gson.toJson(user);
				}
				resp.setStatus(HttpServletResponse.SC_OK);
				resp.getWriter().println(json);
			}
		}
		else if(mode.equals("rating") && action.equals("store"))
		{
			String json = req.getParameter("rating");
			String responseJson = "{}";
			long storedId = 0;
			
			if(json != null)
			{
				try {
					Rating rating = new Rating();
					
					JsonElement jelement = new JsonParser().parse(json);
				    JsonObject  jobject = jelement.getAsJsonObject();
				    String lectureIdString = jobject.get("lectureId").getAsString();
				    long lectureId = Long.parseLong(lectureIdString);
				    String user = jobject.get("username").getAsString();
				    String comment = jobject.get("comment").getAsString();
				    String ratingString = jobject.get("rating").getAsString();
				    int userRating = Integer.parseInt(ratingString);
				   
				    rating.setRating(userRating);
				    rating.setComment(comment);
				    rating.setUser(user);
				    rating.setLecture(new Key<Lecture>(Lecture.class, lectureId));
				    rating.setDate(new Date(System.currentTimeMillis()));
				    
				    storedId = access.storeRating(rating);
				    rating.setId(storedId);
				    
				    //assemble response
				    JsonObject jObj = new JsonObject();
					jObj.addProperty("id", rating.getId());
					jObj.addProperty("lectureId", rating.getLecture().getId());
					jObj.addProperty("user", rating.getUser());
					jObj.addProperty("comment", rating.getComment());
					jObj.addProperty("rating", rating.getRating());
					jObj.addProperty("date", rating.getDate().getTime());
					
					responseJson = jObj.toString();
				    
				}
				catch (JsonSyntaxException ex) {
				}
				catch(NumberFormatException ex) {
				}
				
				resp.setStatus(HttpServletResponse.SC_OK);
				resp.getWriter().println(responseJson);
				
			}
		}
		else if(mode.equals("rating") && action.equals("get") )
		{
			String lectureId = req.getParameter("lectureId");
			
			String json = "[]";
			
			if(lectureId != null) {
				try {
					long integerLectureId = Long.parseLong(lectureId);
					if(integerLectureId == 0) throw new NumberFormatException();
					
					List<Rating> ratingList = access.getRating(integerLectureId);
					if(ratingList != null) {
						JsonArray jArray = new JsonArray();
						for(Rating rating : ratingList)
						{
							JsonObject jObj = new JsonObject();
							jObj.addProperty("id", rating.getId());
							jObj.addProperty("lectureId", rating.getLecture().getId());
							jObj.addProperty("user", rating.getUser());
							jObj.addProperty("comment", rating.getComment());
							jObj.addProperty("rating", rating.getRating());
							jObj.addProperty("date", rating.getDate().getTime());
							jArray.add(jObj);
						}
					    json = jArray.toString();
					}
				}
				catch(NumberFormatException ex) {}
			}
			
			resp.setStatus(HttpServletResponse.SC_OK);
			resp.getWriter().println(json);
			
		}
	}
	
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
	{
		doGet(req, resp);
	}
}
